package com.ruoyi.project.service.impl;

import java.util.Date;
import java.util.List;

import com.ruoyi.common.domainenum.FinRecordVoucherStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.project.common.StaticMethod;
import com.ruoyi.project.domain.FinPackage;
import com.ruoyi.project.service.IFinPackageService;
import com.ruoyi.project.service.IFinRecordVoucherItemService;
import com.ruoyi.project.service.IFinSubjectMonthService;
import org.springframework.stereotype.Service;
import com.ruoyi.common.utils.SecurityUtils;
import javax.annotation.Resource;
import com.ruoyi.project.mapper.FinRecordVoucherMapper;
import com.ruoyi.project.domain.FinRecordVoucher;
import com.ruoyi.project.service.IFinRecordVoucherService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 记账凭证Service业务层处理
 *
 * @author abel
 * @date 2024-10-15
 */
@Service
public class FinRecordVoucherServiceImpl implements IFinRecordVoucherService
{
    @Resource
    private FinRecordVoucherMapper finRecordVoucherMapper;
    @Resource
    private IFinRecordVoucherItemService finRecordVoucherItemService;
    @Resource
    private IFinSubjectMonthService finSubjectMonthService;
    @Resource
    private IFinPackageService finPackageService;
    /**
     * 查询记账凭证
     *
     * @param id 记账凭证ID
     * @return 记账凭证
     */
    @Override
    public FinRecordVoucher selectFinRecordVoucherById(Long id)
    {
        return finRecordVoucherMapper.selectById(id);
    }

    /**
     * 获取记账凭证，获取不到数据抛错
     *
     * @param id 记账凭证ID
     * @return 记账凭证
     */
    @Override
    public FinRecordVoucher getFinRecordVoucherById(Long id)
    {
        FinRecordVoucher finRecordVoucher = finRecordVoucherMapper.selectById(id);
        if(finRecordVoucher == null){
            throw new ServiceException("记账凭证id不正确，没有找到相关数据！");
        }
        return finRecordVoucher;
    }

    /**
     * 查询记账凭证列表
     *
     * @param finRecordVoucher 记账凭证
     * @return 记账凭证
     */
    @Override
    public List<FinRecordVoucher> selectFinRecordVoucherList(FinRecordVoucher finRecordVoucher)
    {
        return finRecordVoucherMapper.selectFinRecordVoucherList(finRecordVoucher);
    }

    /**
     * 新增记账凭证
     *
     * @param finRecordVoucher 记账凭证
     * @return 结果
     */
    @Override
    @Transactional
    public FinRecordVoucher insertFinRecordVoucher(FinRecordVoucher finRecordVoucher)
    {
        if(finRecordVoucherMapper.findByRecordNo(finRecordVoucher.getPackageId(),finRecordVoucher.getRecordTag(),
                finRecordVoucher.getYearValue(),finRecordVoucher.getMonthValue(),finRecordVoucher.getRecordNo())!=null){
            throw new ServiceException("保存失败，凭证字号重复，请检查后重试！");
        }
        StaticMethod.setCreateField(finRecordVoucher,SecurityUtils.getUserId(),SecurityUtils.getUsername());
        FinPackage finPackage = finPackageService.getFinPackageById(finRecordVoucher.getPackageId());
        finRecordVoucher.setYearValue(finPackage.getCurrentYear());
        finRecordVoucher.setMonthValue(finPackage.getCurrentMonth());
        finRecordVoucher.setYearAndMonth(StaticMethod.genYearAndMonth(finRecordVoucher.getYearValue(),finRecordVoucher.getMonthValue()));
        int res = finRecordVoucherMapper.insert(finRecordVoucher);
        finRecordVoucherItemService.createByFinRecord(finRecordVoucher);
        return finRecordVoucher;
    }

    /**
     * 修改记账凭证
     *
     * @param finRecordVoucher 记账凭证
     * @return 结果
     */
    @Override
    @Transactional
    public int updateFinRecordVoucher(FinRecordVoucher finRecordVoucher)
    {
        StaticMethod.setUpdateField(finRecordVoucher,SecurityUtils.getUserId(),SecurityUtils.getUsername());
        int res =  finRecordVoucherMapper.updateById(finRecordVoucher);
        finRecordVoucherItemService.updateByFinRecord(finRecordVoucher);
        return res;
    }

    @Override
    public FinRecordVoucher findNextByInfo(Long packageId, String recordTag, Integer currentYear, Integer currentMonth, Integer recordNo) {
        return finRecordVoucherMapper.findNextByInfo(packageId,recordTag,currentYear,currentMonth,recordNo);
    }

    @Override
    public FinRecordVoucher findPreByInfo(Long packageId, String recordTag, Integer currentYear, Integer currentMonth, Integer recordNo) {
        return finRecordVoucherMapper.findPreByInfo(packageId,recordTag,currentYear,currentMonth,recordNo);
    }

    /**
     * 批量删除记账凭证
     *
     * @param ids 需要删除的记账凭证ID
     * @return 结果
     */
    @Override
    public int deleteFinRecordVoucherByIds(Long[] ids)
    {
        for(Long id:ids){
            deleteFinRecordVoucherById(id);
        }
        return ids.length;
    }

    /**
     * 删除记账凭证信息
     *
     * @param id 记账凭证ID
     * @return 结果
     */
    @Override
    public int deleteFinRecordVoucherById(Long id)
    {
        FinRecordVoucher finRecordVoucher = this.getFinRecordVoucherById(id);
        if(finRecordVoucher.getStatus() != FinRecordVoucherStatus.DRAFT){
            throw new ServiceException("删除失败，只能删除状态为草稿的记账凭证！");
        }
        finRecordVoucherItemService.deleteByRecordId(id);
        return finRecordVoucherMapper.deleteFinRecordVoucherById(id);
    }

    @Override
    public int getMaxRecordNo(Long packageId,String recordTag, Integer currentYear, Integer currentMonth) {
        Integer maxRecordNo = finRecordVoucherMapper.getMaxRecordNo(packageId,recordTag,currentYear,currentMonth);
        return maxRecordNo == null ? 1 : (1+maxRecordNo);
    }

    @Override
    public void check(Long id, boolean result) {
        FinRecordVoucher finRecordVoucher = this.getFinRecordVoucherById(id);
        if(result){
            // 为true时，更改为已审核
            if(finRecordVoucher.getStatus() == FinRecordVoucherStatus.DRAFT){
                finRecordVoucherMapper.updateToChecked(id,FinRecordVoucherStatus.CHECKED,SecurityUtils.getUserId(),SecurityUtils.getUsername(),new Date());
            }else{
                throw new ServiceException("更新失败，凭证状态不正确！");
            }
        }else {
            // 为false时更改为草稿
            if(finRecordVoucher.getStatus() == FinRecordVoucherStatus.CHECKED){
                finRecordVoucherMapper.updateToDraft(id,FinRecordVoucherStatus.DRAFT);
            }else{
                throw new ServiceException("更新失败，凭证状态不正确！");
            }
        }
    }

    @Transactional
    @Override
    public void recordToBook(Long id, boolean result) {
        FinRecordVoucher finRecordVoucher = this.getFinRecordVoucherById(id);
        if(result){
            // 为true时，记账
            if(finRecordVoucher.getStatus() == FinRecordVoucherStatus.CHECKED){
                finRecordVoucherMapper.updateToRecorded(id,FinRecordVoucherStatus.RECORDED,SecurityUtils.getUserId(),SecurityUtils.getUsername(),new Date());
                finSubjectMonthService.recordToBook(finRecordVoucher);
            }else{
                throw new ServiceException("更新失败，凭证状态不正确！");
            }
        }else {
            // 为false时，反记账
            if(finRecordVoucher.getStatus() == FinRecordVoucherStatus.RECORDED){
                finRecordVoucherMapper.updateRecordedBack(id,FinRecordVoucherStatus.CHECKED);
                finSubjectMonthService.recordCancelToBook(finRecordVoucher);
            }else{
                throw new ServiceException("更新失败，凭证状态不正确！");
            }
        }
    }
}
